import t = require('through2');
import gutil = require('gulp-util');
import VFile = require('vinyl');
import stream = require('stream');
import { ZPackOptions, Dict } from './Types';
import Context from './Context';
import File from './file/File';
import SourceFile from './file/SourceFile';
import ModuleFile from './file/ModuleFile';

File.CREATORS[FileType.source] = (cx, op) => new SourceFile(cx, op);
File.CREATORS[FileType.module] = (cx, op) => new ModuleFile(cx, op);

export default function ZPack(aopt: Partial<ZPackOptions> = {}) {

    const cx = new Context(aopt);

    return t.obj(async function pack(vfile: VFile, enc, cb) {
        try {
            if (vfile.isNull()) {
                cb(null, vfile);
                return;
            }
            if (vfile.isStream()) {
                cb(new gutil.PluginError('gulp-zpack', 'Streaming not supported'));
                return;
            }
            cx.transform = this;
            let entryFile = File.obtain(cx, vfile.path);
            await cx.assembly.onFile(entryFile);
            cb();
        } catch (err) {
            console.error(err);
            if (cx.options.avoidError) {
                cb();
            } else {
                cb(new gutil.PluginError(err));
            }
        }
    }, async function (cb) {
        try {
            cx.transform = this;
            await cx.assembly.onFlush();


            cb();
        } catch (err) {
            console.error(err);
            throw err;
        }
    });
}
